<template>
  <view :style="[gridStyle]" class="sc-grid" @tap="tapHandler">
    <slot></slot>
  </view>
</template>

<script>
import { backgroundProps, backgroundStyle } from "../../libs/props/background.js";
import { marginProps, marginStyle } from "../../libs/props/margin.js";
import { paddingProps, paddingStyle } from "../../libs/props/padding.js";
import { positionProps, positionStyle } from "../../libs/props/position.js";
import mpMixin from "../../libs/mixin/mpMixin.js";
import mixin from "../../libs/mixin/mixin.js";

const ALIGN_ITEMS_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  baseline: "baseline",
  stretch: "stretch",
  "first-baseline": "first baseline",
  "last-baseline": "last baseline",
  "safe-center": "safe center"
};

const JUSTIFY_ITEMS_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  baseline: "baseline",
  stretch: "stretch",
  "first-baseline": "first baseline",
  "last-baseline": "last baseline",
  "safe-center": "safe center"
};

const JUSTIFY_CONTENT_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  between: "space-between",
  around: "space-around",
  stretch: "stretch"
};

const ALIGN_CONTENT_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  between: "space-between",
  around: "space-around",
  stretch: "stretch"
};

/**
 * @component sc-grid grid布局组件
 * @property {String|Number}  width           - 组件宽度，支持数值或带单位的字符串，如 100 或 '100rpx'
 * @property {String|Number}  height          - 组件高度，支持数值或带单位的字符串，如 100 或 '100rpx'
 * @property {String|Number}  round           - 组件圆角值，支持数值或带单位的字符串，如 10 或 '10rpx'
 * @property {Number|String}  opacity         - 组件透明度，取值范围 0-1
 * @property {Boolean}        hidden          - 是否隐藏组件，默认 false
 * @property {String}         shadow          - 组件阴影样式，如 '0 2px 4px rgba(0, 0, 0, 0.1)'
 * @property {String}         border          - 组件边框样式，如 '1rpx solid #000'
 * @property {String|Number}  col             - 网格列数，支持具体数值或 CSS grid-template-columns 的完整值
 * @property {String|Number}  row             - 网格行数，支持具体数值或 CSS grid-template-rows 的完整值
 * @property {String}         areas           - 网格区域布局，如 'a b c' 'd e f' 'g h i'
 * @property {String}         ai              - 单元格垂直对齐方式，可选值：start/center/end/around/between/evenly
 * @property {String}         ji              - 单元格水平对齐方式，可选值：start/center/end/around/between/evenly
 * @property {String}         jc              - 整体内容水平对齐方式，可选值：start/end/center/between/around/evenly/baseline等
 * @property {String}         ac              - 整体内容垂直对齐方式，可选值：start/end/center/between/around/evenly/baseline等
 * @property {Number|String}  zIndex          - 组件层级
 * @property {String|Number}  gap             - 网格间距，同时设置行列间距
 * @property {String|Number}  rowGap          - 行间距，默认 0
 * @property {String|Number}  colGap          - 列间距，默认 0
 * @property {Object}         customStyle     - 自定义样式对象
 * @property {Object}         backgroundProps - 背景相关属性
 * @property {Object}         marginProps     - 外边距相关属性
 * @property {Object}         paddingProps    - 内边距相关属性
 * @property {Object}         positionProps   - 定位相关属性
 * 
 * @event {Function} click - 点击事件
 */

export default {
  name: "ScGrid",
  mixins: [mpMixin, mixin],
  props: {
    width: {
      type: [String, Number],
    },
    height: {
      type: [String, Number],
    },
    round: {
      type: [String, Number],
    },
    opacity: {
      type: [Number, String],
    },
    hidden: {
      type: Boolean,
      default: false,
    },
    shadow: {
      type: String,
    },
    border: {
      type: String,
    },
    col: {
      type: [String, Number],
    },
    row: {
      type: [String, Number],
    },
    areas: {
      type: String,
    },
    ai: {
      type: String,
    },
    ji: {
      type: String,
    },
    jc: {
      type: String,
    },
    ac: {
      type: String,
    },
    zIndex: {
      type: [Number, String],
    },
    gap: {
      type: [String, Number],
    },
    rowGap: {
      type: [String, Number],
      default: 0,
    },
    colGap: {
      type: [String, Number],
      default: 0,
    },
    customStyle: {
      type: Object,
      default: () => ({}),
    },
    ...backgroundProps,
    ...marginProps,
    ...paddingProps,
    ...positionProps,
  },
  emits: ["click"],
  data() {
    return {};
  },
  computed: {
    gridStyle() {
      const baseStyle = {
        display: "grid",
        width: this.width && this.$sc.addUnit(this.width),
        height: this.height && this.$sc.addUnit(this.height),
        borderRadius: this.round && this.$sc.addUnit(this.round),
        opacity: this.opacity,
        boxShadow: this.shadow,
        border: this.border,
        overflow: this.hidden && "hidden",
        zIndex: this.zIndex,
        gridTemplateColumns: this.getGridTemplateColumns(),
        gridTemplateRows: this.getGridTemplateRows(),
        gridTemplateAreas: this.areas,
        gridGap: this.gap || `${this.$sc.addUnit(this.rowGap)} ${this.$sc.addUnit(this.colGap)}`,
        alignItems: this.ai && ALIGN_ITEMS_MAP[this.ai],
        justifyItems: this.ji && JUSTIFY_ITEMS_MAP[this.ji],
        alignContent: this.ac && ALIGN_CONTENT_MAP[this.ac],
        justifyContent: this.jc && JUSTIFY_CONTENT_MAP[this.jc]
      };
      return this.$sc.deepMerge(baseStyle, backgroundStyle(this),
        marginStyle(this),
        paddingStyle(this),
        positionStyle(this),
        this.customStyle);
    }
  },
  methods: {
    tapHandler() {
      this.$emit("click");
    },
    getGridTemplateColumns() {
      if (/^\d+$/.test(this.col)) {
        return `repeat(${this.col}, 1fr)`;
      }
      return this.col;
    },
    getGridTemplateRows() {
      if (/^\d+$/.test(this.row)) {
        return `repeat(${this.row}, 1fr)`;
      }
      return this.row;
    },
    getGridTemplateAreas() {
      return this.areas.map(subArr => subArr.join(' '));
    }
  }
};
</script>

<style lang="scss" scoped>
.sc-grid {
  box-sizing: border-box;
  display: grid;
}
</style>
